#pragma once

#ifndef SIMU_OPTINS
#define SIMU_OPTINS

#include <core/error.h>
#include <core/queue.h>
#include <core/typedef.h>

enum SimuOptType {
    SIMU_OPT_STRING = 0,  /* no parsing (use string as-is)                        */
    SIMU_OPT_BOOL,        /* on/off                                               */
    SIMU_OPT_NUMBER,      /* simple number                                        */
    SIMU_OPT_SIZE,        /* size, accepts (K)ilo, (M)ega, (G)iga, (T)era postfix */
};

typedef struct SimuOptDesc {
    const char* name;
    enum SimuOptType type;
    const char* help;
    const char* def_value_str;
} SimuOptDesc;

struct SimuOpt {
    char* name;
    char* str;

    const SimuOptDesc* desc;
    union {
        bool boolean;
        uint64_t uint;
    } value;

    SimuOpts* opts;
    QTAILQ_ENTRY(QemuOpt) next;
};

struct SimuOpts {
    char* id;
    SimuOptsList* list;
    Location loc;
    QTAILQ_HEAD(, SimuOpt) head;
    QTAILQ_ENTRY(SimuOpts) next;
};


struct SimuOptsList {
    const char* name;
    const char* implied_opt_name;
    bool merge_lists;  /* Merge multiple uses of option into a single list? */
    QTAILQ_HEAD(, SimuOpts) head;
    SimuOptDesc desc[];
};

void simu_add_opts(SimuOptsList* list);
void simu_add_drive_opts(SimuOptsList* list);
#endif // !SIMU_OPTINS
